go-micro-v3 框架整体介绍
go-micro v3组件
- 注册(
Registry
):提供了服务发现机制 - 选择器(
Selector
):能够实现负载均衡 - 传输(
Transport
):服务与服务之间通信接口 - 代理(
Broker
):提供异步通信的消息发布、订阅接口 - 编码(
Codec
):消息传输到两端时进行编码与解码 Server
服务端,Client
客户端
go-micro v3技术栈
- 注册中心&配置中心
- 链路追踪
- 熔断
- 限流
- 日志中心
- 监控
注册中心和配置中心consul集群
docker-compose
镜像引入consul
集群版base
基础工程添加consul
consul
控制面板添加配置
配置docker-compose的consul集群
version: '3'
services:
# 注册中心集群版本设置
consul1:
image: cap1573/consul
container_name: node1
# 以 server 模式启动
command: agent -server -bootstrap-expect=3 -node=node1 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
consul2:
image: cap1573/consul
container_name: node2
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node2 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
consul3:
image: cap1573/consul
container_name: node3
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node3 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
# 添加对外暴露的节点 启动控制面板
consul4:
image: consul
container_name: node4
command: agent -retry-join=node1 -node=node4 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1 -ui
ports:
- 8500:8500
depends_on:
- consul2
- consul3
# 启动
docker-compose up
访问:http://127.0.0.1:8500/ui/dc1/services/consul/instances
base服务添加consul
完成注册中心
go get github.com/asim/go-micro/plugins/registry/consul/v3
func main() {
consul := consul.NewRegistry(func(options *regstry.Options) {
options.Addrs = []string{
// 如果放到 docker-compose 也可以是服务名称
// 这里暂时是本地可以写 localhost
"localhost:8500",
}
});
// ... 其他省略代码
service := micro.NewService(
micro.Name("base-wj"),
micro.Version("latest"),
micro.Registry(consul),
)
service.Init()
base.RegisterBaseHandler(service.Server(), new(handler.BaseHandler))
// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}
编写完成之后,我们可以启动一下服务。
我们可以看到base
服务已经注册到consul
配置中心
我们另外在项目的平级目录下新建common
目录用于配置配置项。
go mod init git.xxx.com/用户名/common
go get github.com/asim/go-micro/v3/config
go get github.com/asim/go-micro/plugins/config/source/consul/v3
config.go
package common
import (
"github.com/asim/go-micro/plugins/config/source/consul/v3"
"github.com/asim/go-micro/v3/config"
"strconv"
)
func GetConsulConfig(host string, port int64, prefix string) (config.Config, error) {
consulSource := consul.NewSource(
//设置配置中心的地址
consul.WithAddress(host+":"+strconv.FormatInt(port, 10)),
//设置前缀,不设置 /micro/config
consul.WithPrefix(prefix),
consul.StripPrefix(true),
)
conf, err := config.NewConfig()
if err != nil {
return conf, err
}
err = conf.Load(consulSource)
return conf, err
}
写完之后,可以上传一下代码,可以让同级目录下的可以进行引入使用对应的配置内容。
然后我们继续到base
服务代码中获取配置项
func main() {
consul := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{
"localhost:8500",
}
})
//2.配置中心,存放经常变动的变量
consulConfig, err := common.GetConsulConfig("localhost", consulPort, "/micro/config")
if err != nil {
//common.Error(err)
fmt.Println(err)
}
fmt.Println(consulConfig)
service := micro.NewService(
micro.Name("base-wj"),
micro.Version("latest"),
micro.Registry(consul),
)
service.Init()
base.RegisterBaseHandler(service.Server(), new(handler.BaseHandler))
// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}
启动base
服务后去consul
中创建key/value
{
"host": "127.0.0.1",
"port": 3306,
"user": "root",
"pwd": "123456",
"database": "paas"
}
注意
这里一定要选择json
编写mysql结构体和使用配置中心连接mysql
结构体和刚才建立的
json
内容需要一一对应
我们在commom
模块中新建mysql.go
package common
import "github.com/asim/go-micro/v3/config"
// MysqlConfig 创建结构体
type MysqlConfig struct {
Host string `json:"host"`
User string `json:"user"`
Pwd string `json:"pwd"`
Database string `json:"database"`
Port string `json:"port"`
}
func GetMysqlFromConsul(config config.Config, path ...string) *MysqlConfig {
mysqlConfig := &MysqlConfig{}
config.Get(path...).Scan(mysqlConfig)
return mysqlConfig
}
commmon
模块编写之后,需要上传一下,不然别的模块的还是无法使用新的代码,别的模块等到上传完之火,还需要重新go get
一下更新一下代码。
从配置中心获取配置并使用gorm
连接mysql
func main() {
//需要本地启动,mysql,consul中间件服务
//1.注册中心
//consul := consul.NewRegistry(func(options *registry.Options) {
// options.Addrs = []string{
// consulHost + ":" + strconv.FormatInt(consulPort, 10),
// }
//})
consul := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{
"localhost:8500",
}
})
//2.配置中心,存放经常变动的变量
consulConfig, err := common.GetConsulConfig("localhost", consulPort, "/micro/config")
if err != nil {
//common.Error(err)
fmt.Println(err)
}
fmt.Println(consulConfig)
//3.使用配置中心连接 mysql
// 这里的path是相对于 /micro/config 目录路径
mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
//初始化数据库
db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@("+mysqlInfo.Host+":3306)/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
if err != nil {
//命令行输出下,方便查看错误
fmt.Println(err)
}
defer db.Close()
//禁止复表 创建表不带s
db.SingularTable(true)
// 创建服务
service := micro.NewService(
micro.Name("base-wj"),
micro.Version("latest"),
micro.Registry(consul),
)
service.Init()
base.RegisterBaseHandler(service.Server(), new(handler.BaseHandler))
// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}
在docker-compose
里配置一个mysql5.6
的服务
version: '3'
services:
# 注册中心集群版本设置
consul1:
image: cap1573/consul
container_name: node1
# 以 server 模式启动
command: agent -server -bootstrap-expect=3 -node=node1 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
consul2:
image: cap1573/consul
container_name: node2
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node2 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
consul3:
image: cap1573/consul
container_name: node3
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node3 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
# 添加对外暴露的节点 启动控制面板
consul4:
image: consul
container_name: node4
command: agent -retry-join=node1 -node=node4 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1 -ui
ports:
- 8500:8500
depends_on:
- consul2
- consul3
# 添加数据库
paas-mysql:
image: cap1573/mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 123456
container_name: paas-mysql
# 我们这里换个端口,本地已经有3306了
ports:
- "3308:3306"
# 需要将重要的数据挂盘
volumes:
- ./mysql:/var/lib/mysql
然后我们重新启动一下docker-compose up
测试连接通过,表示服务启动成功。连接成功后,并新建一个数据库.然后再base
服务中不要忘记安装gorm
的一些需要的mysql
驱动。
注意
db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@("+mysqlInfo.Host+":3306)/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
这里如果你本机和容器映射的端口都是3306无所谓,如果你本地有,你换了一个,这里也得换,所以你对应的配置中心的端口也得换。后面如果是在容器里连接,那就可能会换成对应的服务名。
重新启动base
服务